﻿/********************************************************************************/
/* 	0724th - player.d															*/
/*------------------------------------------------------------------------------*/
/*	製作		（　゜ワ゜）ノ　／　松久貫太									*/
/*	製作開始　	2007/05/11														*/
/*	MAIL		omega@personal.email.ne.jp										*/
/*	URL		http://nagoya.cool.ne.jp/o_mega										*/
/*																				*/
/*	このソースは「やらわかライセンス」の元で配布されています。					*/
/*-更新履歴---------------------------------------------------------------------*/
/*	2007/--/--																	*/
/*-その他-----------------------------------------------------------------------*/
/*	なし																		*/
/********************************************************************************/

/* ライブラリのインポート *******************************************************/
private import hell2;		// dHell2ライブラリ
private import actor;
private import vector;
private import screen;
private import keypad;
private import state;
private import shot;
private import effect;

private import std.string;
private import std.math;
private import std.math2;
private import std.stream;

/**/

class Player : Actor
{
private:
	static const float ORIGINAL_SPEED = 0.07;
	static const float ARRANGE_SPEED = 0.1;
	static const float PLAYER_SIZE = 0.8;
	
	static const float ROT_SPEED = 0.2;
	static const float WIRE_ROT_SPEED = 0.07;
	
	static const int ROLLING_INPUT_WAIT = 30;
	static const int ROLLING_MAX = 10;
	static const float ROLLING_GRAZESIZE = 1.5;
	static const float NORMAL_GRAZESIZE = 2;
public:
	Vec3 rotation;
	Vec3 rot_speed;
	Vec3 wire_rotation;
	Vec3 wire_rot_speed;
	int timer;
	
	int keyUpDown_timer;
	int keyLeftRight_timer;
	int rolling;
	
	GameMain gamemain;
	
	this(GameMain gm)
	{
		gamemain = gm;
		position = new Vec3(0,0,-20);
		timer = 0;
		
		exist = true;
		
		rot_speed = new Vec3();
		rotation = new Vec3( Hell_randInt(-100,100) / 4.0 ,
						Hell_randInt(-100,100) / 4.0 ,
						Hell_randInt(-100,100) / 4.0 );
		wire_rot_speed = new Vec3();
		wire_rotation = new Vec3( Hell_randInt(-100,100) / 4.0 ,
						Hell_randInt(-100,100) / 4.0 ,
						Hell_randInt(-100,100) / 4.0 );
		
		keyLeftRight_timer = 0;
		keyUpDown_timer = 0;
		rolling = 0;
	}
	
	void move()
	{
		if(!exist) return;
		
		timer++;
		moveByArrowKey();
		checkCollisionToShot();
		
		rotation += rot_speed;
		rotation *= 0.94;
		rotation.z += 0.4;
		wire_rotation += wire_rot_speed;
		wire_rot_speed *= 0.98;
		wire_rotation.z -= 0.2;
		
		if(rolling > 0 && keyUpDown_timer < 1 && keyLeftRight_timer < 1)
		{
			rolling--;
		}
	}
	
	void moveByArrowKey()
	{
		float vx,vy;
		vx = vy = 0;
		
		if(isPressDown())
		{
			vy = 1;
			rot_speed.y += ROT_SPEED;
			wire_rot_speed.y -= WIRE_ROT_SPEED;
		}
		if(isPressUp())
		{
			vy = -1;
			rot_speed.y -= ROT_SPEED;
			wire_rot_speed.y += WIRE_ROT_SPEED;
		}
		if(isPressLeft())
		{
			vx = -1;
			rot_speed.x -= ROT_SPEED;
			wire_rot_speed.x += WIRE_ROT_SPEED;
		}
		if(isPressRight())
		{
			vx = 1;
			rot_speed.x += ROT_SPEED;
			wire_rot_speed.x -= WIRE_ROT_SPEED;
		}
		
		
		// ローリング入力判定時間
		if(keyUpDown_timer > 0)	keyUpDown_timer--;
		if(keyLeftRight_timer > 0)	keyLeftRight_timer--;
		
		// ローリング関係
		if(isPushDown() || isPushUp())
		{
			if(keyUpDown_timer > 0) rolling++;
			keyUpDown_timer = ROLLING_INPUT_WAIT;
		}
		if(isPushLeft() || isPushRight())
		{
			if(keyLeftRight_timer > 0) rolling++;
			keyLeftRight_timer = ROLLING_INPUT_WAIT;
		}
		if(rolling > ROLLING_MAX) rolling = ROLLING_MAX;
		if(isRolling())
		{
			rot_speed.z -= ROT_SPEED * 2;
			wire_rot_speed.z += WIRE_ROT_SPEED * 2;
		}
		
		// 斜め補正
		if(vx * vy != 0)
		{
			vx *= 0.7;
			vy *= 0.7;
		}
		
		if(gamemain.rule == GameMain.RULE.ORIGINAL)
		{
			position.x += vx * ORIGINAL_SPEED;
			position.y += vy * ORIGINAL_SPEED;
		}
		else
		{
			position.x += vx * ARRANGE_SPEED;
			position.y += vy * ARRANGE_SPEED;
		}
		
		if(position.x > 20.0)
		{
			position.x = 20.0;
		}
		if(position.x < -20.0)
		{
			position.x = -20.0;
		}
		if(position.y > 15.0)
		{
			position.y = 15.0;
		}
		if(position.y < -15.0)
		{
			position.y = -15.0;
		}
	}
	
	void checkCollisionToShot()
	{
		Shot s = gamemain.shotactor.getNearestShot(position);
		
		if(s){
			if( s.position.getDist(position) < getSize() + s.getSize())
			{
				// Destory
				exist = false;
				
				for(int t=0;t<64;t++)
				{
					gamemain.effectactor.add(position , position , EFFECTTYPE.TRIANGLE);
					gamemain.effectactor.add(position , position , EFFECTTYPE.LINE);
				}
			}
		}
	}
	
	void draw()
	{
		if(!exist) return;
		
		glPushMatrix();
		
		{
			glLoadIdentity();
			glTranslatef(position.x , position.y , position.z);
			glRotatef(rotation.x , rotation.y , rotation.z);
			
			glScalef(PLAYER_SIZE ,PLAYER_SIZE ,PLAYER_SIZE);
			glColor4f(0.1, 1.0, 0.4, 0.3);
			BulletShape.drawPolygon();
			glColor4f(0.5, 1.0, 0.75, 0.9);
			BulletShape.drawWire();
		}
		glPopMatrix();
		
		glPushMatrix();
		if(gamemain.rule != GameMain.RULE.ORIGINAL){
			glLoadIdentity();
			glTranslatef(position.x , position.y , -20.f);
			glRotatef(wire_rotation.x , wire_rotation.y , wire_rotation.z);
			
			float r = getGrazeSize();
			glScalef(r,r,r);
			glColor4f(0.1 ,1.0 ,0.4 ,0.7);
			BulletShape.drawWire();
		}
		glPopMatrix();
	}
	void drawStatus()
	{
		//Hell_drawFont(std.string.toString(cast(int)keyUpDown_timer),320 ,320 ,0.5 );
	}
	
	float getSize()
	{
		return PLAYER_SIZE;
	}
	
	bool isRolling()
	{
		if(gamemain.rule == GameMain.RULE.ORIGINAL) return 0;
		if(rolling > ROLLING_MAX / 2) return true;
		return false;
	}
	
	float getGrazeSize()
	{
		if(gamemain.rule == GameMain.RULE.ORIGINAL) return 0;
		return cast(float)rolling / cast(float)ROLLING_MAX * ROLLING_GRAZESIZE + NORMAL_GRAZESIZE;
	}
}